import {ref, computed} from 'vue'
import {defineStore} from 'pinia'
import {useKeyStore} from "@/stores/keyStore.js";
import {useRightMenuStore} from "@/stores/rightMenu.js";
import * as fileApi from "@/api/fileApi.js";
import {usePreviewImgStore} from "@/stores/previewImgStore.js";
import {usePreviewVideoStore} from "@/stores/previewVideoStore.js";
import {usePreviewAudioStore} from "@/stores/previewAudioStore.js";
import {usePreviewInfoStore} from "@/stores/previewInfoStore.js";
import {usePreviewStore} from "@/stores/previewStore.js";
import {useMessageStore} from "@/stores/message.js";

export const useFileListStore = defineStore('fileListStore', () => {
    const files = ref([])
    const loadFiles = ref([])
    const curPath = ref('')
    const curPathArr = computed(() => {
        let arr = curPath.value.replace("/",`\\`).split("\\").filter(i => i !== '')
        if(arr.length > 0) arr[0] = arr[0] + "\\"
        return arr
    })
    // 是否正在进行选择操作的标志位
    const isSelecting = ref(false);
    // 是否清除选中元素
    const isClear = ref(false);
    // 记录鼠标按下时的坐标
    let startX = 0;
    let startY = 0;
    // 引用选择矩形元素
    const selectionRect = ref(null);
    // 存储被选中的文件元素
    const selectedFiles = ref(new Set());
    const selectedFileIds = ref(new Set());
    // 临时储存文件
    const tempSelectedFiles = ref(new Set());
    // 背景色
    const mouseIntoBG = 'rgba(0, 122, 204, 0.1)'
    const defaultBG = 'rgba(0, 0, 0, 0)'
    const selectBG = 'rgba(0, 122, 204, 0.3)'

    /**
     * 处理鼠标按下事件
     * @param event 鼠标事件对象
     */
    function handleMouseDown(event) {
        if(usePreviewStore().preShow) return;
        tempSelectedFiles.value.clear()
        let fileElement = event.target.closest('.file');

        // 按下了一个文件
        if (fileElement !== null) {
            if(useKeyStore().keyDown(["Shift"])) {
                delDownFile(event,fileElement)
            }else {
                downFile(event,fileElement);
            }
            return;
        }

        if(event.target.closest('.path-navigation')) {
            return;
        }
        // 没有按下元素 而是空白页面 画框
        // 如果是鼠标右键
        if (event.button === 2) return
        // 开始选择
        isSelecting.value = true;
        // 当没有按住ctrl键才可以清除
        if (!useKeyStore().keyDownAny(["Control","Shift"])) isClear.value = true
        // 记录鼠标按下的坐标
        startX = event.pageX;
        startY = event.pageY;
        // 禁用文本选择以避免浏览器默认行为
        document.body.style.userSelect = 'none';
        // 创建并显示选择矩形
        createSelectionRect(startX, startY);
    }

    /**
     * 处理鼠标移动事件
     * @param event 鼠标事件对象
     */
    function handleMouseMove(event) {
        if (!isSelecting.value) return;
        isClear.value = false;

        let width = event.pageX - startX;
        let height = event.pageY - startY;

        let newLeft = width < 0 ? event.pageX : startX;
        let newTop = height < 0 ? event.pageY : startY;

        width = Math.abs(width);
        height = Math.abs(height);

        Object.assign(selectionRect.value.style, {
            left: `${newLeft}px`,
            top: `${newTop}px`,
            width: `${width}px`,
            height: `${height}px`
        });
        updateSelectedElements(newLeft, newTop, width, height);
    }

    /**
     * 处理鼠标松开事件
     * @param event 鼠标事件对象
     */
    function handleMouseUp(event) {
        // 如果当前正在进行选择操作
        if (!isSelecting.value) return
        // 结束选择操作
        isSelecting.value = false;
        // 恢复文本选择
        document.body.style.userSelect = '';
        // 移除选择矩形
        if (selectionRect.value) document.body.removeChild(selectionRect.value);
        selectionRect.value = null;
    }

    /**
     * 处理文档点击事件
     * @param event 鼠标事件对象
     */
    async function handleDocumentClick(event) {
        // 如果点击的是页面空白处（即非 .file 区域 非 .rightMenu 区域）
        if (isClear.value && !event.target.closest('.file') && !event.target.closest(".rightMenu")) {
            clearSelect();
        }
    }

    function clearSelect() {
        // 清除所有已选中的文件项的背景颜色，并清空 selectedFiles 集合
        selectedFiles.value.forEach(fileElement => {
            fileElement.style.backgroundColor = '';
        });
        selectedFiles.value.clear();
        selectedFileIds.value.clear()
    }

    /**
     * 创建选择矩形
     * @param x 矩形起始点的 X 坐标
     * @param y 矩形起始点的 Y 坐标
     */
    function createSelectionRect(x, y) {
        if(useRightMenuStore().showMenu) return;
        if(usePreviewImgStore().show) return;
        if(usePreviewVideoStore().show) return;
        if(usePreviewAudioStore().show) return;
        if(usePreviewInfoStore().show) return;
        if(useMessageStore().show) return;

        selectionRect.value = document.createElement('div');

        Object.assign(selectionRect.value.style, {
            position: 'absolute',
            top: `${y + window.scrollY}px`, // 考虑滚动条偏移
            left: `${x + window.scrollX}px`, // 考虑滚动条偏移
            width: '0px',
            height: '0px',
            backgroundColor: selectBG,
            border: '1px solid rgba(0, 122, 204, 0.8)',
            zIndex: 1000,
            pointerEvents: 'none'
        });

        document.body.appendChild(selectionRect.value);
    }

    /**
     * 更新被选中的文件元素列表
     * @param left 选择矩形的左边距
     * @param top 选择矩形的上边距
     * @param width 选择矩形的宽度
     * @param height 选择矩形的高度
     */
    function updateSelectedElements(left, top, width, height) {
        if(useRightMenuStore().showMenu) return
        // 获取所有 .selectable-container 元素
        const allFiles = getAllFiles();

        allFiles.forEach(fileElement => {
            const rect = fileElement.getBoundingClientRect()

            // **转换 rect 到 page 坐标**
            const fileLeft = rect.left + window.scrollX;
            const fileTop = rect.top + window.scrollY;
            const fileRight = rect.right + window.scrollX;
            const fileBottom = rect.bottom + window.scrollY;
            let marquee = !(fileRight < left || fileLeft > left + width || fileBottom < top || fileTop > top + height);

            // 按下了shift
            if (useKeyStore().keyDownAny(["Shift"])) {
                if (marquee) {
                    if (selectedFiles.value.has(fileElement)) {
                        addTempFile(fileElement)
                    }
                    delFile(fileElement)
                } else {
                    if (tempSelectedFiles.value.has(fileElement)) {
                        addFile(fileElement)
                        delTempFile(fileElement)
                    }
                }
                return
            }
            // 按下了ctrl
            if(useKeyStore().keyDownAny(["Control"])) {
                if (marquee) {
                    if (!selectedFiles.value.has(fileElement)) {
                        addTempFile(fileElement)
                    }
                    addFile(fileElement)
                } else {
                    if (tempSelectedFiles.value.has(fileElement)) {
                        delFile(fileElement)
                        delTempFile(fileElement)
                    }
                }
                return
            }
            // 什么也没按
            if (marquee) {
                addFile(fileElement)
            } else {
                delFile(fileElement)
            }
        });
    }


    /**
     * 获取全部文件元素
     */
    function getAllFiles() {
        return document.querySelectorAll('.file');
    }

    function dragstartHandler(event) {
        let elementById = document.getElementById("preImg");
        const originalWidth = elementById.offsetWidth;
        const originalHeight = elementById.offsetHeight;

        elementById.innerHTML = '';
        elementById.style.position = 'absolute';
        elementById.style.top = '-9999px'; // 将元素移出可视区域
        elementById.style.width = originalWidth + 'px';
        elementById.style.height = originalHeight + 'px';

        let div = document.createElement('div');
        div.style.position = 'relative'; // 父容器使用相对定位
        div.style.display = 'inline-block'; // 根据需求调整显示方式
        elementById.appendChild(div);

        let index = 0;
        let num = selectedFiles.value.size;
        selectedFiles.value.forEach((fileElement) => { // 假设selectedFiles是一个数组
            const clonedFileElement = fileElement.cloneNode(true);
            let imgElement = clonedFileElement.querySelector('.file .component-file-img'); // 获取图片元素
            imgElement.style.position = 'absolute'; // 设置图片为绝对定位
            imgElement.style.width = '100px'; // 设置宽度
            imgElement.style.height = '100px'; // 设置高度
            imgElement.style.left = (index++ * 15) + 'px'; // 根据索引计算left值
            imgElement.style.zIndex = num--; // 调整z-index，使左侧图片位于上方

            div.appendChild(imgElement); // 添加到父容器中
        });

        event.dataTransfer.setDragImage(elementById, 0, 0);
    }

    /**
     * 处理鼠标进入事件（鼠标悬停）
     * @param event 鼠标事件对象
     */
    function handleMouseEnter(event) {
        if(useRightMenuStore().showMenu) return
        const fileElement = event.target.closest('.file');
        if (fileElement && !selectedFiles.value.has(fileElement) && window.getComputedStyle(fileElement).backgroundColor === defaultBG) {
            fileElement.style.backgroundColor = mouseIntoBG;
        }
    }

    /**
     * 处理鼠标离开事件
     * @param event 鼠标事件对象
     */
    function handleMouseLeave(event) {
        if(useRightMenuStore().showMenu) return
        const fileElement = event.target.closest('.file');
        if (fileElement && !selectedFiles.value.has(fileElement) && window.getComputedStyle(fileElement).backgroundColor === mouseIntoBG) {
            fileElement.style.backgroundColor = defaultBG;
        }
    }

// 处理拖拽进入目标区域
    function handleDragOver(event) {
        event.preventDefault(); // 必须调用这个方法来允许拖放

        // 判断目标区域是否是目录
        const target = event.target.closest('.file');
        let obj = JSON.parse(target.getAttribute('data-obj'));
        event.dataTransfer.dropEffect = (obj.directory && !obj.drive && !selectedFiles.value.has(target))
            ? 'move'
            : 'none'
    }

// 处理拖拽放置事件
    function handleDrop(event) {
        event.preventDefault();

        const target =  event.target.closest('.file');
        if(selectedFiles.value.has(target)) return
        let obj = JSON.parse(target.getAttribute('data-obj'));
        selectedFiles.value.forEach(item => console.log(JSON.parse(item.getAttribute('data-obj')).absolutePath))
        console.log(obj.absolutePath)
        console.log("放置成功")
    }

    function addFile(fileElement) {
        fileElement.style.backgroundColor = selectBG;
        selectedFiles.value.add(fileElement)
        selectedFileIds.value.add(JSON.parse(fileElement.getAttribute('data-obj')).id)
    }

    function delFile(fileElement) {
        fileElement.style.backgroundColor = defaultBG;
        selectedFiles.value.delete(fileElement)
        selectedFileIds.value.delete(JSON.parse(fileElement.getAttribute('data-obj')).id)
    }

    function addTempFile(fileElement) {
        tempSelectedFiles.value.add(fileElement)
    }

    function delTempFile(fileElement) {
        tempSelectedFiles.value.delete(fileElement)
    }

    function addAllFile() {
        const allFiles = getAllFiles()
        allFiles.forEach(item => addFile(item))
    }

    function downFile(event,fileElement) {
        // if(event.button === 2) {
            // 发送到右键菜单 等待点击选择按钮
            useRightMenuStore().updateReceiveDownFile(fileElement)
            // return
        // }

        // 点击了一个新的元素 并且没有按住ctrl
        if (!selectedFiles.value.has(fileElement) && !useKeyStore().keyDown(["Control"])) {
            clearSelect()
        }
        addFile(fileElement)

        // 1. 将该元素添加到 selectedFiles 的第一位
        selectedFiles.value = new Set([fileElement, ...selectedFiles.value]);
        selectedFileIds.value = new Set([JSON.parse(fileElement.getAttribute('data-obj')).id, ...selectedFileIds.value]);

        // 2. 设置该元素在最上面（通过调整 z-index）
        const size = selectedFiles.value.size
        selectedFiles.value.forEach((el, index) => el.style.zIndex = size - index - 1); // 其他元素的 z-index 递减
        fileElement.style.zIndex = size; // 被鼠标点的元素设置一个较高的 z-index 值
    }

    function counterSelection() {
        let allFiles = new Set(getAllFiles())
        selectedFiles.value.forEach((fileElement) => {allFiles.delete(fileElement)})
        selectedFiles.value.forEach((fileElement) => {delFile(fileElement)})
        allFiles.forEach((fileElement) => {addFile(fileElement)})
    }

    function selectFile(element) {
        selectedFiles.value.has(element) ? delFile(element) : addFile(element)
    }

    function delDownFile(event,fileElement) {
        // 点击了一个新的元素 并且没有按住ctrl
        delFile(fileElement)
    }

    async function apiList(path,name) {
        const res = await fileApi.list(path,name);
        files.value = res.data
        loadFiles.value = []
        loadFileGradually()
    }

    function loadFileGradually(idx) {
        let index = !idx ? 0 : idx;
        if (index < files.value.length) {
            loadFiles.value.push(files.value[index])
            index++;
            setTimeout(() => loadFileGradually(index),files.value.length > 100 ? 10 : 25)
        }
    }

    function isMobileDevice() {
        return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
    }

    return {
        files,
        isSelecting,
        isClear,
        startX,
        startY,
        selectionRect,
        selectedFiles,
        selectedFileIds,
        mouseIntoBG,
        defaultBG,
        selectBG,
        handleMouseDown,
        handleMouseMove,
        handleMouseUp,
        handleDocumentClick,
        clearSelect,
        createSelectionRect,
        updateSelectedElements,
        dragstartHandler,
        handleMouseEnter,
        handleMouseLeave,
        handleDragOver,
        handleDrop,
        addFile,
        delFile,
        getAllFiles,
        addAllFile,
        counterSelection,
        selectFile,
        apiList,
        curPath,
        curPathArr,
        loadFiles,
        isMobileDevice
    }
})
